package com.jinzecloud.fiction.service.impl;

import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.google.code.kaptcha.Producer;
import com.jinzecloud.fiction.execption.Code;
import com.jinzecloud.fiction.utils.PageUtils;
import com.jinzecloud.fiction.utils.Query;
import com.jinzecloud.fiction.utils.R;
import com.jinzecloud.fiction.utils.RedisUtils;
import com.jinzecloud.fiction.vo.TbAdminVo;
import com.jinzecloud.fiction.vo.TbAdminVos;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.RedisConnectionFailureException;
import org.springframework.stereotype.Service;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.ConnectException;
import java.net.http.HttpResponse;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jinzecloud.fiction.mapper.TbAdminMapper;
import com.jinzecloud.fiction.bean.TbAdmin;
import com.jinzecloud.fiction.service.TbAdminService;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@Slf4j
@Service("tbAdminService")
public class TbAdminServiceImpl extends ServiceImpl<TbAdminMapper, TbAdmin> implements TbAdminService {

    @Autowired
    private Producer producer;
    @Autowired
    TbAdminMapper tbAdminMapper;
    @Autowired
    RedisUtils redisUtils;
    @Autowired
    HttpServletRequest request;

    @Value("${fiction.admin.code}")
    String codePrefix;
    @Value("${fiction.admin.token}")
    String tokenPrefix;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<TbAdmin> tbAdminQueryWrapper = new QueryWrapper<>();
        String key = (String) params.get("key");
        if (!StringUtils.isEmpty(key)) {
            tbAdminQueryWrapper.eq("ad_id", key).or().like("ad_user_name", key);
        }

        IPage<TbAdmin> page = this.page(
                new Query<TbAdmin>().getPage(params), tbAdminQueryWrapper
        );
        PageUtils pageUtils = new PageUtils(page);
        List<TbAdmin> admins = page.getRecords();
        List<TbAdminVo> list = admins.stream().map(tbAdmin -> {
            TbAdminVo tbAdminVo = new TbAdminVo();
            BeanUtils.copyProperties(tbAdmin, tbAdminVo);
            return tbAdminVo;
        }).collect(Collectors.toList());
        pageUtils.setList(list);
        return pageUtils;
    }

    @Override
    public void updateStatus(TbAdmin tbAdmin) {
        UpdateWrapper<TbAdmin> tbAdminUpdateWrapper = new UpdateWrapper<>();
        tbAdminUpdateWrapper.eq("ad_id", tbAdmin.getAdId()).set("ad_status", tbAdmin.getAdStatus());
        tbAdminMapper.update(null, tbAdminUpdateWrapper);
    }

    @Override
    public void saveTbAdmin(TbAdmin tbAdmin) {
        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String format = simpleDateFormat.format(date);
        tbAdmin.setAdUserPassword(SecureUtil.md5(tbAdmin.getAdUserPassword()));
        tbAdmin.setAdCreationTime(format);
        tbAdmin.setAdStatus("1");
        tbAdminMapper.insert(tbAdmin);
    }

    @Override
    public void updateTbAdminById(TbAdmin tbAdmin) {
        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String format = simpleDateFormat.format(date);
        tbAdmin.setAdUpdateTime(format);
        tbAdmin.setAdUserPassword(SecureUtil.md5(tbAdmin.getAdUserPassword()));
        UpdateWrapper<TbAdmin> tbAdminUpdateWrapper = new UpdateWrapper<>();
        tbAdminMapper.updateById(tbAdmin);
    }

    @Override
    public R getByUsernameAndPassword(TbAdminVos tbAdminVos) throws Exception {
        Map map = new HashMap();
        String authcode = tbAdminVos.getAuthcode();
        System.out.println(redisUtils.hget(codePrefix + authcode,authcode));
        String code = (String) redisUtils.hget(codePrefix + authcode,authcode);
        if (StringUtils.isEmpty(code)) {
            return R.error(Code.CODEPASTDUE_EXCEPTION.getCode(), Code.CODEPASTDUE_EXCEPTION.getMsg());
        }
        if (!tbAdminVos.getUuid().equals(code)) {
            return R.error(Code.CODE_EXCEPTION.getCode(), Code.CODE_EXCEPTION.getMsg());
        } else {
            String passwords = SecureUtil.md5(tbAdminVos.getAdUserPassword());
            QueryWrapper<TbAdmin> tbAdminQueryWrapper = new QueryWrapper<>();
            tbAdminQueryWrapper.eq("ad_user_name", tbAdminVos.getAdUserName()).eq("ad_user_password", passwords);
            TbAdmin tbAdmin = this.getOne(tbAdminQueryWrapper);
            if (tbAdmin != null) {
                TbAdminVo tbAdminVo = new TbAdminVo();
                BeanUtils.copyProperties(tbAdmin, tbAdminVo);
                String uuid = UUID.randomUUID().toString();
                redisUtils.set(tokenPrefix + uuid, tbAdminVo, 60 * 30);
                map.put("token", uuid);
                return R.ok().put("data", map);
            }
            return R.error(Code.USERNAMEANDPASSWORD_EXCEPTION.getCode(), Code.USERNAMEANDPASSWORD_EXCEPTION.getMsg());
        }
    }

    @Override
    public void getCode(HttpServletRequest request,HttpServletResponse response, String uuid) throws Exception{
        //生成文字验证码
        String code = producer.createText();
        // 获取图片验证码
        BufferedImage image = producer.createImage(code);
        redisUtils.hset(codePrefix + code, code,uuid, 180);
        // 直接在浏览器页面进行显示
        response.setHeader("Cache-Control", "no-store, no-cache");
        response.setContentType("image/jpeg");
        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(image, "jpg", out);
        IOUtils.closeQuietly(out);
//        return R.ok().put("img",ImageIO);
    }

    @Override
    public R Logout(String token) {
        TbAdminVo tbAdminVo = (TbAdminVo) redisUtils.get(token);
        if (tbAdminVo == null) {
            return R.ok();
        }
        redisUtils.del(token);
        return R.ok();
    }

    @Override
    public TbAdminVo getUserInfo(String token) {
        TbAdminVo tbAdminVo = (TbAdminVo) redisUtils.get(tokenPrefix + token);
        return tbAdminVo;
    }
}